home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #1 / Amiga Plus 1999 #1.iso / System-Boost / Workbench / LFSystemBinder / compagnons / Registry / Compagons / PatchAssign.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-21  |  7.9 KB  |  265 lines

  1. /*
  2.  *  PatchAssign.c
  3.  *      © LFSoft 1995
  4.  *
  5.  *  Notify when assign are changed.
  6.  *
  7.  *      Version 1.0
  8.  *  30/07/1995  First version. Resource "ASSIGN"
  9.  *  02/08/1995  More tests for cleanup()
  10.  *
  11.  *      Version 1.1
  12.  *  07/08/1995  Why only notifing for assign? New resources "RESIDENT" and
  13.  *              "ENVVAR" allow notification for resident commands and for
  14.  *              environnement variables.
  15.  *   ^
  16.  *  /!\ CAUTION: Removing patch is never a safe thing !
  17.  *  ¯T¯
  18.  *      NOTE: + When a delayed resident (in a CSH compatible way - CSH 5.20+,
  19.  *  LFSystemBinder, ...- ) is added (or deleted) you are notified for ENVVAR
  20.  *  modification. When a delayed resident is invoqued for the first time, you
  21.  *  are notified from "ENVVAR" and "RESIDENT".
  22.  *            + For EnvVar my first idea was to use a DOS notification, but,
  23.  *  unfortunaly, variable deletion isn't notified. So, i patch SetVar() and
  24.  *  DeleteVar() too and i look for !GVF_LOCAL_ONLY flag. We still need to use
  25.  *  dos notifications for programs that directly write to ENV: like my very own
  26.  *  DiceConfig...
  27.  *            + Already locked "ASSIGN" resource meens PatchAssign is already
  28.  *  running.
  29.  *
  30.  *  CTRL-C for exist.
  31.  *
  32.  *      This code is fully a dommain public: Use it as you want...
  33.  *  Note: This code use my very own LFatal() function to display an alert
  34.  *  when error occur. You must change it to a new one if you want to compile
  35.  *  this source.
  36.  *
  37.  */
  38.  
  39. #include <proto/exec.h>
  40. #include <proto/registry.h>
  41. #include <proto/dos.h>
  42. #include <LF.h>         // For LFatal()
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45.  
  46. extern struct Library *DOSBase;
  47. struct Library *RegistryBase=NULL;
  48.  
  49. APTR    resass=NULL, resres = NULL, resenv = NULL;
  50.  
  51. struct NotifyRequest req;
  52.  
  53. BOOL (*oldfaa)(__D1 STRPTR,__D2 BPTR) = NULL;     // AssignAdd
  54. BOOL (*oldfalt)(__D1 STRPTR,__D2 STRPTR) = NULL;    // AssignLate
  55. BOOL (*oldfalc)(__D1 STRPTR,__D2 BPTR) = NULL;    // AssignLock
  56. BOOL (*oldfap)(__D1 STRPTR,__D2 STRPTR) = NULL;     // AssignPath
  57. BOOL (*oldfra)(__D1 STRPTR,__D2 BPTR) = NULL;     // RemAssignList
  58.  
  59. LONG (*oldfas)(__D1 STRPTR, __D2 BPTR, __D3 LONG) = NULL;    // AddSegment
  60. LONG (*oldfrs)(__D1 struct Segment *) = NULL;    // RemSegment
  61.  
  62. BOOL (*oldfsv)(__D1 STRPTR, __D2 STRPTR, __D3 LONG, __D4 ULONG) = NULL;     // SetVar
  63. BOOL (*oldfdv)(__D1 STRPTR,__D2 ULONG) = NULL;     // DeleteVar
  64.  
  65. BOOL regassok = FALSE;
  66.  
  67. void cleanup() {
  68.     if(RegistryBase){
  69.         if(regassok) RL_UnLockResource(resass);
  70.         RL_UnRegisterResource(resass);
  71.         RL_UnRegisterResource(resres);
  72.         RL_UnRegisterResource(resenv);
  73.         CloseLibrary(RegistryBase);
  74.     }
  75. }
  76.  
  77. __geta4 BOOL myassadd(__D1 STRPTR nom, __D2 BPTR path){
  78.     BOOL ret = oldfaa(nom,path);
  79.     if(ret) RL_Notify(resass);
  80.     return ret;
  81. }
  82.  
  83. __geta4 BOOL myasslate(__D1 STRPTR nom, __D2 STRPTR path){
  84.     BOOL ret = oldfalt(nom,path);
  85.     if(ret) RL_Notify(resass);
  86.     return ret;
  87. }
  88.  
  89. __geta4 BOOL myasslock(__D1 STRPTR nom, __D2 BPTR path){
  90.     BOOL ret = oldfalc(nom,path);
  91.     if(ret) RL_Notify(resass);
  92.     return ret;
  93. }
  94.  
  95. __geta4 BOOL myasspath(__D1 STRPTR nom, __D2 STRPTR path){
  96.     BOOL ret = oldfap(nom,path);
  97.     if(ret) RL_Notify(resass);
  98.     return ret;
  99. }
  100.  
  101. __geta4 BOOL myremasslist(__D1 STRPTR nom, __D2 BPTR path){
  102.     BOOL ret = oldfra(nom,path);
  103.     if(ret) RL_Notify(resass);
  104.     return ret;
  105. }
  106.  
  107. __geta4 LONG myaddsegment(__D1 STRPTR nom, __D2 BPTR seg, __D3 LONG type){
  108.     LONG ret = oldfas(nom,seg,type);
  109.     if(ret) RL_Notify(resres);
  110.     return ret;
  111. }
  112.  
  113. __geta4 LONG myremsegemnt(__D1 struct Segment *seg){
  114.     LONG ret = oldfrs(seg);
  115.     if(ret) RL_Notify(resres);
  116.     return ret;
  117. }
  118.  
  119. __geta4 BOOL mysetvar(__D1 STRPTR name, __D2 STRPTR buffer, __D3 LONG size, __D4 ULONG flags){
  120.     BOOL ret = oldfsv(name,buffer,size,flags);
  121.     if(ret && !(flags & GVF_LOCAL_ONLY)) RL_Notify(resenv);
  122.     return ret;
  123. }
  124.  
  125. __geta4 BOOL mydeletevar(__D1 STRPTR name, __D2 ULONG flags){
  126.     BOOL ret = oldfdv(name,flags);
  127.     if(ret && !(flags & GVF_LOCAL_ONLY)) RL_Notify(resenv);
  128.     return ret;
  129. }
  130.  
  131. void debut( void ){
  132.     if(!(RegistryBase = OpenLibrary("registry.library",0))){
  133.         LFatal("Can't open registry.library");
  134.         exit(20);
  135.     }
  136.     atexit(cleanup);
  137.  
  138.     req.nr_Name = "Env:";
  139.     req.nr_Flags = NRF_SEND_SIGNAL;
  140.     req.nr_stuff.nr_Signal.nr_Task = FindTask(NULL);
  141.     req.nr_stuff.nr_Signal.nr_SignalNum = SIGBREAKB_CTRL_F;
  142.  
  143.     if(!StartNotify(&req)){
  144.         puts("Error from StartNotify(\"Env:\")");
  145.         exit(20);
  146.     }
  147.  
  148.         // register our resouces
  149.     if(!(resass=RL_RegisterResource("ASSIGN"))){
  150.         LFatal("Can't register my resouce");
  151.         exit(20);
  152.     }
  153.  
  154.     if(!(resres=RL_RegisterResource("RESIDENT"))){
  155.         LFatal("Can't register my resouce");
  156.         exit(20);
  157.     }
  158.  
  159.     if(!(resenv=RL_RegisterResource("ENVVAR"))){
  160.         LFatal("Can't register my resouce");
  161.         exit(20);
  162.     }
  163.  
  164.         // Lock exclusively the resource
  165.     if(!(regassok = RL_LockResource(resass,FALSE))){
  166.         LFatal("PatchAssign should be already running");
  167.         exit(20);
  168.     }
  169.  
  170.     oldfaa = SetFunction(DOSBase, -630, myassadd);
  171.     oldfalt = SetFunction(DOSBase, -618, myasslate);
  172.     oldfalc = SetFunction(DOSBase, -612, myasslock);
  173.     oldfap = SetFunction(DOSBase, -624, myasspath);
  174.     oldfra = SetFunction(DOSBase, -636, myremasslist);
  175.  
  176.     oldfas = SetFunction(DOSBase, -774, myaddsegment);
  177.     oldfrs = SetFunction(DOSBase, -786, myremsegemnt);
  178.  
  179.     oldfsv = SetFunction(DOSBase, -900, mysetvar);
  180.     oldfdv = SetFunction(DOSBase, -912, mydeletevar);
  181.  
  182.     FOREVER {
  183.         ULONG sig = Wait(SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_F);
  184.  
  185.         if(sig & SIGBREAKF_CTRL_F)
  186.             RL_Notify(resenv);
  187.  
  188.         if(sig & SIGBREAKF_CTRL_C){
  189.             APTR vect;
  190.             BOOL ok = TRUE;
  191.  
  192.             Forbid();   // Test if nobody have changed our patch
  193.  
  194.             vect = SetFunction(DOSBase, -630, NULL);
  195.             SetFunction(DOSBase, -630, vect);
  196.             if(vect != myassadd) ok = FALSE;
  197.  
  198.             vect = SetFunction(DOSBase, -618, NULL);
  199.             SetFunction(DOSBase, -618, vect);
  200.             if(vect != myasslate) ok = FALSE;
  201.  
  202.             vect = SetFunction(DOSBase, -612, NULL);
  203.             SetFunction(DOSBase, -612, vect);
  204.             if(vect != myasslock) ok = FALSE;
  205.  
  206.             vect = SetFunction(DOSBase, -624, NULL);
  207.             SetFunction(DOSBase, -624, vect);
  208.             if(vect != myasspath) ok = FALSE;
  209.  
  210.             vect = SetFunction(DOSBase, -636, NULL);
  211.             SetFunction(DOSBase, -636, vect);
  212.             if(vect != myremasslist) ok = FALSE;
  213.  
  214.             vect = SetFunction(DOSBase, -774, NULL);
  215.             SetFunction(DOSBase, -774, vect);
  216.             if(vect != myaddsegment) ok = FALSE;
  217.  
  218.             vect = SetFunction(DOSBase, -786, NULL);
  219.             SetFunction(DOSBase, -786, vect);
  220.             if(vect != myremsegemnt) ok = FALSE;
  221.  
  222.             vect = SetFunction(DOSBase, -900, NULL);
  223.             SetFunction(DOSBase, -900, vect);
  224.             if(vect != mysetvar) ok = FALSE;
  225.  
  226.             vect = SetFunction(DOSBase, -912, NULL);
  227.             SetFunction(DOSBase, -912, vect);
  228.             if(vect != mydeletevar) ok = FALSE;
  229.  
  230.             if(ok) break;
  231.             else {
  232.                 Permit();
  233.                 LFatal("PatchAssign can't be removed");
  234.             }
  235.         }
  236.     }
  237.  
  238.     SetFunction(DOSBase, -630, oldfaa);     // AssignAdd
  239.     SetFunction(DOSBase, -618, oldfalt);    // AssignLate
  240.     SetFunction(DOSBase, -612, oldfalc);    // AssignLock
  241.     SetFunction(DOSBase, -624, oldfap);     // AssignPath
  242.     SetFunction(DOSBase, -636, oldfra);     // RemAssignList
  243.  
  244.     SetFunction(DOSBase, -774, oldfas);     // AddSegment
  245.     SetFunction(DOSBase, -786, oldfrs);     // RemSegment
  246.  
  247.     SetFunction(DOSBase, -900, oldfsv);     // SetVar
  248.     SetFunction(DOSBase, -912, oldfdv);     // DeleteVar
  249.  
  250.     Permit();
  251.  
  252.     EndNotify(&req);
  253.  
  254.     exit(0);
  255. }
  256.  
  257. void main(){
  258.     PutStr("  PatchAssign v1.1 ("__TIME__" "__DATE__")\n"
  259.         "\t© LFSoft 1995\n");
  260.     debut();
  261. }
  262.  
  263. void wbmain(){
  264.     debut();
  265. }